/*
 * Copyright 2010-2012 Susanta Tewari. <freecode4susant@users.sourceforge.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package db.genomemap;

import db.gui.RDBConnection;
import db.gui.RDBConnectionModel;

import genomemap.data.ChData;

import javautil.io.IOUtil;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Collection;
import java.util.HashSet;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * database settings for the application
 * @author Susanta Tewari
 * @version 1.0
 * @updated 20-Nov-2007 7:37:55 PM
 */
public class RDBSettings implements Serializable {

    /** Field description */
    public static final String SERVER_TYPE_MYSQL = "MySQL";

    /** Field description */
    public static final String SERVER_TYPE_MSSQL = "MSSQL";

    /** Field description */
    public static final String SERVER_TYPE_ORACLE = "Oracle";

    /** Field description */
    public static final String DRIVER_TYPE_MYSQL = "com.mysql.jdbc.Driver";


    // TABLE NAMES

    /** Field description */
    public static final String TABLE_CHROMOSOME = "chromosome";

    /** Field description */
    public static final String TABLE_CLONE = "clone";

    /** Field description */
    public static final String TABLE_PROBE = "probe";

    /** Field description */
    public static final String TABLE_GENE = "genes";

    /** Field description */
    public static final String TABLE_RFLP = "rflp";

    /** Field description */
    public static final String TABLE_NCU = "ncu";


    // 7 hybrid tables for all chromosomes,1 for each. pattern :hybrid_1,hybrid_2,...etc

    /** Field description */
    public static final String TABLE_HYBRID_PTRN = "hybrid_";

    /** Field description */
    private static final long serialVersionUID = 42L;

    /** Field description */
    private static final String ownPath = "resources/RDBSettings.obj";

    /** Field description */
    private RDBConnectionModel defaultConnectionModel = null;

    /** Field description */
    private Collection<RDBConnectionModel> storedConections = new HashSet<>();

    /**
     * Constructs ...
     */
    public RDBSettings() {}

    public static Collection<String> getTableNames() {

        Collection<String> collection = new HashSet<>();

        collection.add(TABLE_CHROMOSOME);
        collection.add(TABLE_CLONE);
        collection.add(TABLE_PROBE);
        collection.add(TABLE_GENE);
        collection.add(TABLE_RFLP);
        collection.add(TABLE_NCU);

        for (int i = 1; i <= 7; i++) {

            collection.add(TABLE_HYBRID_PTRN + i);
        }

        return collection;
    }

    public static void main(String[] args) {

        RDBSettings rdbSettings  = RDBSettings.load();
        RDBConnectionModel model = new RDBConnectionModel();

        rdbSettings.setDefaultConnectionModel(model);
        rdbSettings.commit();
    }

    public ChData getChData(int ch_id) {

        ChData chData = new ChData();

        try {

            RDBConnection dbConnection = new RDBConnection();
            Statement stmt             = dbConnection.getStatement();

            if (stmt == null) {
                return null;
            }

            ResultSet rs = null;
            String query = null;


//          get other statistics related to the chromosome
            query =
                "SELECT ch_length, clone_length, gene_count, probe_count,clone_count, prob_false_pos, prob_false_neg, hybridTable FROM chromosome WHERE ch_id = "
                + ch_id + ";";
            rs = stmt.executeQuery(query);

            rs.next();
            chData.setChLength(rs.getInt("ch_length"));
            chData.setCloneLength(rs.getInt("clone_length"));
            chData.setGeneCount(rs.getInt("gene_count"));
            chData.setCloneCount(rs.getInt("clone_count"));
            chData.setProbFalsePos(rs.getDouble("prob_false_pos"));
            chData.setProbFalseNeg(rs.getDouble("prob_false_neg"));
            chData.setHybridTable(rs.getString("hybridTable"));

        } catch (SQLException ex) {
            Logger.getLogger(RDBSettings.class.getName()).log(Level.SEVERE, null, ex);
        }

        return chData;
    }

    public static RDBSettings load() {

        RDBSettings rdbSettings = null;

        try {
            rdbSettings = (RDBSettings) IOUtil.unMarshall(new File(ownPath));
        } catch (IOException | ClassNotFoundException ex) {
            ex.printStackTrace();
        } finally {
            return rdbSettings;
        }
    }

    /**
     * object serialization. rdb serialization should only occur as a
     * separate dedicated process but not as frequently as object serialization.
     * commit returns success status. if a single commit fails the application should
     * send a warning for saving data at different levels of serialization
     * (or does it sutomatically as a background job).
     */
    public boolean commit() {

        boolean commitSucceeded = true;

        try {
            IOUtil.marshall(new File(ownPath), this);
        } catch (Exception ex) {

            ex.printStackTrace();

            commitSucceeded = false;

        } finally {
            return commitSucceeded;
        }
    }

    public RDBConnectionModel getDefaultConnectionModel() {
        return defaultConnectionModel;
    }

    public void setDefaultConnectionModel(RDBConnectionModel defaultConnectionModel) {

        this.defaultConnectionModel = defaultConnectionModel;

        this.commit();
    }

    Collection<RDBConnectionModel> getStoredConections() {
        return storedConections;
    }

    public void setStoredConections(Collection<RDBConnectionModel> storedConections) {

        this.storedConections = storedConections;

        this.commit();
    }

    public void addStoredConnection(RDBConnectionModel rdbConnectionModel) {

        getStoredConections().add(rdbConnectionModel);
        commit();
    }
}
